#include "hc595.h"

unsigned int num[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xff, 0x00};
//创建一个数组，0-9所对应的十六进制数
/**********************************/
/** 函数名称：void HC595_Write_Data(unsigned char dis_data) **/
/** 输入参数：unsigned char dis_data 需要输入的数据  */
/** 函数功能：将数据写进74HC595中*/
/** ****************************** **/
void HC595_Write_Data(unsigned char dis_data)
{
	unsigned char i;
	unsigned char temp_1;
	temp_1 = dis_data;
	for(i=0;i<8;i++)    //    循环将一个字节的八位依次写入到寄存器
	{
		HAL_GPIO_WritePin(STCP_1_GPIO_Port,STCP_1_Pin,GPIO_PIN_RESET);// 	SRCLK低电平
		if(temp_1 & 0X80)
		{
			HAL_GPIO_WritePin(DS_1_GPIO_Port,DS_1_Pin,GPIO_PIN_SET);
		}
		else
		{
			HAL_GPIO_WritePin(DS_1_GPIO_Port,DS_1_Pin,GPIO_PIN_RESET);
		}
		temp_1 = temp_1<<1;
		HAL_GPIO_WritePin(STCP_1_GPIO_Port,STCP_1_Pin,GPIO_PIN_RESET);	// 	SRCLK低电平
		HAL_GPIO_WritePin(STCP_1_GPIO_Port,STCP_1_Pin,GPIO_PIN_SET);		// 	SRCLK高电平
	}
}
 
/****************************************/
/**函数名称：void Disp_out(void)*/
/**函数参数：无参*/
/**函数功能：将写入到寄存器的数据输出到端口显示*/
/****************************************/
void Disp_out(void)
{
	HAL_GPIO_WritePin(SHCP_1_GPIO_Port,SHCP_1_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(SHCP_1_GPIO_Port,SHCP_1_Pin,GPIO_PIN_SET);
}

// 显示单个数码管的封装函数
void Display_Single_Digit(unsigned char position, unsigned char value)
{
    HC595_Write_Data(position);  // 片选数码管
    HC595_Write_Data(value);    // 显示对应的值
    Disp_out();
    HAL_Delay(2);               // 延时1ms
}

// 显示4321的封装函数
void Display_4321(void)
{
    Display_Single_Digit(0x01, num[4]);  // 显示4
    Display_Single_Digit(0x02, num[3]);  // 显示3
    Display_Single_Digit(0x04, num[2]);  // 显示2
    Display_Single_Digit(0x08, num[2]);  // 显示1
}

// 显示整数的封装函数
void Display_Integer(int number)
{
    unsigned char positions[] = {0x08, 0x04, 0x02, 0x01}; // 从高位到低位的数码管片选
    unsigned char digits[4] = {0}; // 存储拆分后的每一位数字
    int i = 0;

    // 拆分整数的每一位数字（从个位到千位）
    while (number > 0 && i < 4)
    {
        digits[i] = number % 10; // 获取当前最低位
        number /= 10;            // 去掉最低位
        i++;
    }

    // 显示每一位数字（从高位到低位）
    for (int j = 3; j >= 0; j--)
    {
        if (j >= 4 - i) // 只显示有效位
        {
            Display_Single_Digit(positions[j], num[digits[3 - j]]);
        }
        else
        {
            Display_Single_Digit(positions[j], num[10]); // 显示空白
        }
    }
}
/**********************************/
/** 函数名称：void HC595_Write_Data(unsigned char dis_data) **/
/** 输入参数：unsigned char dis_data 需要输入的数据  */
/** 函数功能：将数据写进74HC595中*/
/** ****************************** **/
void HC595_1_Write_Data(unsigned char dis_data)
{
	unsigned char i;
	unsigned char temp;
	temp = dis_data;
	for(i=0;i<8;i++)    //    循环将一个字节的八位依次写入到寄存器
	{
		HAL_GPIO_WritePin(STCP_GPIO_Port,STCP_Pin,GPIO_PIN_RESET);// 	SRCLK低电平
		if(temp & 0X80)
		{
			HAL_GPIO_WritePin(DS_GPIO_Port,DS_Pin,GPIO_PIN_SET);
		}
		else
		{
			HAL_GPIO_WritePin(DS_GPIO_Port,DS_Pin,GPIO_PIN_RESET);
		}
		temp = temp<<1;
		HAL_GPIO_WritePin(STCP_GPIO_Port,STCP_Pin,GPIO_PIN_RESET);	// 	SRCLK低电平
		HAL_GPIO_WritePin(STCP_GPIO_Port,STCP_Pin,GPIO_PIN_SET);		// 	SRCLK高电平
	}
}
 
/****************************************/
/**函数名称：void Disp_out(void)*/
/**函数参数：无参*/
/**函数功能：将写入到寄存器的数据输出到端口显示*/
/****************************************/
void Disp_1_out(void)
{
	HAL_GPIO_WritePin(SHCP_GPIO_Port,SHCP_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(SHCP_GPIO_Port,SHCP_Pin,GPIO_PIN_SET);
}

// 显示单个数码管的封装函数
void Display_1_Single_Digit(unsigned char position, unsigned char value)
{
    HC595_1_Write_Data(position);  // 片选数码管
    HC595_1_Write_Data(value);    // 显示对应的值
    Disp_1_out();
    HAL_Delay(2);               // 延时2ms
}

// 显示4321的封装函数
void Display_1_4321(void)
{
    Display_1_Single_Digit(0x01, num[4]);  // 显示4
    Display_1_Single_Digit(0x02, num[3]);  // 显示3
    Display_1_Single_Digit(0x04, num[2]);  // 显示2
    Display_1_Single_Digit(0x08, num[2]);  // 显示1
}

// 显示整数的封装函数
void Display_1_Integer(int number)
{
    unsigned char positions[] = {0x08, 0x04, 0x02, 0x01}; // 从高位到低位的数码管片选
    unsigned char digits[4] = {0}; // 存储拆分后的每一位数字
    int i = 0;

    // 拆分整数的每一位数字（从个位到千位）
    while (number > 0 && i < 4)
    {
        digits[i] = number % 10; // 获取当前最低位
        number /= 10;            // 去掉最低位
        i++;
    }

    // 显示每一位数字（从高位到低位）
    for (int j = 3; j >= 0; j--)
    {
        if (j >= 4 - i) // 只显示有效位
        {
            Display_1_Single_Digit(positions[j], num[digits[3 - j]]);
        }
        else
        {
            Display_1_Single_Digit(positions[j], num[10]); // 显示空白
        }
    }
}


// 同时显示两对数码管的封装函数
void Display_Two_Digit_Groups(int number1, int number2)
{
    unsigned char positions[] = {0x08, 0x04, 0x02, 0x01}; // 从高位到低位的数码管片选
    unsigned char digits1[4] = {0}; // 存储第一组数码管的每一位数字
    unsigned char digits2[4] = {0}; // 存储第二组数码管的每一位数字
    int i = 0;

    // 拆分第一组数码管的整数的每一位数字
    while (number1 > 0 && i < 4)
    {
        digits1[i] = number1 % 10; // 获取当前最低位
        number1 /= 10;             // 去掉最低位
        i++;
    }

    i = 0; // 重置计数器

    // 拆分第二组数码管的整数的每一位数字
    while (number2 > 0 && i < 4)
    {
        digits2[i] = number2 % 10; // 获取当前最低位
        number2 /= 10;             // 去掉最低位
        i++;
    }

    // 显示两组数码管的每一位数字
    for (int j = 3; j >= 0; j--)
    {
        // 显示第一组数码管
        if (j >= 4 - i) // 只显示有效位
        {
            Display_Single_Digit(positions[j], num[digits1[3 - j]]);
        }
        else
        {
            Display_Single_Digit(positions[j], num[10]); // 显示空白
        }

        // 显示第二组数码管
        if (j >= 4 - i) // 只显示有效位
        {
            Display_1_Single_Digit(positions[j], num[digits2[3 - j]]);
        }
        else
        {
            Display_1_Single_Digit(positions[j], num[10]); // 显示空白
        }
    }
}

//2









